﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace OG_UPDATETOOL
{
    public static class BootloaderProtocolHelper
    {
        public enum BOOTCMD
        {
            BOOT_INFO = 0x00,
            TEST = 0x01,
            ERASE_FLASH = 0x02,
            BURN = 0x03,
            END_BURN = 0x04,
            CRC = 0x05,
            CRC_CHECK = 0x06,
            BURN_ACK = 0xAA,
            REBOOT = 0xF1,
            JUMP_APP = 0xF2,
        };

        public static byte[] GetCmd(BOOTCMD cmd)
        {
            byte[] ret;
            switch (cmd)
            {
                case BOOTCMD.BOOT_INFO:
                    byte[] firmInfo = { 0xFE, 0xA5, (byte)BOOTCMD.BOOT_INFO };
                    ret = firmInfo;
                    break;
                case BOOTCMD.TEST:
                    byte[] connectTest = { 0xFE, 0xA5, (byte)BOOTCMD.TEST };
                    ret = connectTest;
                    break;
                case BOOTCMD.ERASE_FLASH:
                    byte[] eraseFlash = { 0xFE, 0xA5, (byte)BOOTCMD.ERASE_FLASH };
                    ret = eraseFlash;
                    break;
                case BOOTCMD.BURN:
                    byte[] burn = { 0xFE, 0xA5, (byte)BOOTCMD.BURN };
                    ret = burn;
                    break;
                case BOOTCMD.END_BURN:
                    byte[] end_burn = { 0xFE, 0xA5, (byte)BOOTCMD.END_BURN, 0xAA, 0x58, 0xAA, 0x59 };
                    ret = end_burn;
                    break;
                case BOOTCMD.CRC:
                    byte[] crc = { 0xFE, 0xA5, (byte)BOOTCMD.CRC };
                    ret = crc;
                    break;
                case BOOTCMD.CRC_CHECK:
                    byte[] crc_check = { 0xFE, 0xA5, (byte)BOOTCMD.CRC_CHECK };
                    ret = crc_check;
                    break;
                case BOOTCMD.REBOOT:
                    byte[] reboot = { 0xFE, 0xA5, (byte)BOOTCMD.REBOOT };
                    ret = reboot;
                    break;
                case BOOTCMD.JUMP_APP:
                    byte[] jumpApp = { 0xFE, 0xA5, (byte)BOOTCMD.JUMP_APP };
                    ret = jumpApp;
                    break;
                default:
                    ret = null;
                    break;
            }
            return ret;
        }

        public static byte[] GetCmd(BOOTCMD cmd,UInt16 crc)
        {
            byte[] ret = null;
            switch (cmd)
            {
                case BOOTCMD.BOOT_INFO:
                    break;
                case BOOTCMD.TEST:
                    break;
                case BOOTCMD.ERASE_FLASH:
                    break;
                case BOOTCMD.BURN:
                    break;
                case BOOTCMD.END_BURN:
                    break;
                case BOOTCMD.CRC:
                    
                    var tmp = GetCmd(BOOTCMD.CRC);
                    byte[] tmp1 = new byte[tmp.Length + 2];
                    for(int ii =0;ii<tmp.Length;ii++)
                    {
                        tmp1[ii] = tmp[ii];
                    }
                    tmp1[tmp.Length] = (byte)(crc >> 8);
                    tmp1[tmp.Length + 1] = (byte)(crc);
                    ret = tmp1;
                    break;
                case BOOTCMD.CRC_CHECK:
                    break;
                case BOOTCMD.REBOOT:
                    break;
                case BOOTCMD.JUMP_APP:
                    break;
                default:
                    break;
            }
            return ret;
        }
        /// <summary>
        /// 将bytebuffer翻译为cmd指令
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static bool byteToCmd(out BOOTCMD cmd, byte[] buffer)
        {
            cmd = BOOTCMD.BOOT_INFO;
            if (buffer[0] == 0xFE && buffer[1] == 0x5A)
            {
                switch (buffer[2])
                {
                    case (byte)BOOTCMD.BOOT_INFO:
                        break;
                    case (byte)BOOTCMD.TEST:
                        break;
                    case (byte)BOOTCMD.ERASE_FLASH:
                        break;
                    case (byte)BOOTCMD.BURN:
                        break;
                    case (byte)BOOTCMD.END_BURN:
                        break;
                    case (byte)BOOTCMD.BURN_ACK:
                        break;
                    case (byte)BOOTCMD.CRC:
                        break;
                    case (byte)BOOTCMD.CRC_CHECK:
                        break;
                    case (byte)BOOTCMD.REBOOT:
                        break;
                    case (byte)BOOTCMD.JUMP_APP:
                        break;
                    default:
                        return false;
                }
                cmd = (BOOTCMD)buffer[2];
            }
            else
            {
                return false;
            }
            return true;
        }

        public static string GetInfo(byte[] serialRaw)
        {
            try
            {
                var rawLength = serialRaw.Length - 3;
                byte[] raw = new byte[rawLength];
                for (int ii = 0; ii < serialRaw.Length - 3; ii++)
                {
                    raw[ii] = serialRaw[ii + 3];
                }
                var str = Encoding.UTF8.GetString(raw);
                return str;
            }
            catch(Exception)
            {
                return null;
            }
            
        }

        public static bool GetCrcResult(byte[] resultInfoRaw)
        {
            try
            {
                if (resultInfoRaw[3] == 1)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch(Exception)
            {
                return false;
            }
        }
    }

    
}
